// app/controller/customer_controller.js
'use strict';

const Controller = require('egg').Controller;

class CustomerController extends Controller {
  // 获取客户列表
  async index() {
    const { ctx } = this;
    const { 
      page = 1, 
      limit = 20, 
      name,
      status,
      level,
      type,
      region,
      industry,
      customerSource,
      responsibleSalesman,
      minAnnualAmount,
      maxAnnualAmount,
      sortField,
      sortOrder
    } = ctx.query;

    try {
      // 构建查询条件
      const where = {};
      
      // 添加组织过滤条件
      if (ctx.state.organizationId) {
        where.organizationId = ctx.state.organizationId;
      }

      if (name) {
        where.name = {
          [ctx.app.Sequelize.Op.like]: `%${name}%`
        };
      }

      if (status) {
        where.status = status;
      }

      // 构建排序条件
      let order = [['createdAt', 'DESC']];
      if (sortField && sortOrder) {
        order = [[sortField, sortOrder.toUpperCase()]];
      }

      // 分页查询
      const offset = (parseInt(page) - 1) * parseInt(limit);
      const { rows, count } = await ctx.model.CustomerModel.findAndCountAll({
        where,
        order,
        limit: parseInt(limit),
        offset,
        include: [
          {
            model: ctx.model.ContactPersonModel,
            as: 'contacts',
            attributes: ['id', 'name', 'phone', 'email', 'department', 'position', 'isPrimary']
          }
        ]
      });

      ctx.page(rows, count, parseInt(page), parseInt(limit));
    } catch (error) {
      ctx.logger.error('获取客户列表失败:', error);
      ctx.error('获取客户列表失败');
    }
  }

  // 获取客户详情
  async show() {
    const { ctx } = this;
    const { id } = ctx.params;

    try {
      const customer = await ctx.model.CustomerModel.findByPk(id, {
        include: [
          {
            model: ctx.model.ContactPersonModel,
            as: 'contacts',
            attributes: ['id', 'name', 'phone', 'email', 'department', 'position', 'isPrimary', 'address', 'remark']
          }
        ]
      });

      if (!customer) {
        ctx.error('客户不存在', 404);
        return;
      }

      ctx.success(customer);
    } catch (error) {
      ctx.logger.error('获取客户详情失败:', error);
      ctx.error('获取客户详情失败');
    }
  }

  // 创建客户
  async create() {
    const { ctx } = this;
    const customerData = ctx.request.body;

    try {
      // 设置组织ID
      if (ctx.state.organizationId) {
        customerData.organizationId = ctx.state.organizationId;
      } else {
        customerData.organizationId = 1; // 默认组织ID
      }

      // 开启事务处理
      const result = await ctx.model.transaction(async (t) => {
        // 创建客户
        const customer = await ctx.model.CustomerModel.create(customerData, { transaction: t });

        // 处理联系人信息
        if (customerData.contactPersons && Array.isArray(customerData.contactPersons)) {
          const contactPersons = customerData.contactPersons.map(contact => ({
            ...contact,
            customerId: customer.id
          }));
          await ctx.model.ContactPersonModel.bulkCreate(contactPersons, { transaction: t });
        }

        // 重新查询客户信息，包含联系人
        return await ctx.model.CustomerModel.findByPk(customer.id, {
          include: [
            {
              model: ctx.model.ContactPersonModel,
              as: 'contacts',
              attributes: ['id', 'name', 'phone', 'email', 'department', 'position', 'isPrimary', 'address', 'remark']
            }
          ],
          transaction: t
        });
      });

      ctx.success(result, '客户创建成功');
    } catch (error) {
      ctx.logger.error('创建客户失败:', error);
      ctx.error(`创建客户失败: ${error.message}`);
    }
  }

  // 更新客户
  async update() {
    const { ctx } = this;
    const { id } = ctx.params;
    const customerData = ctx.request.body;

    try {
      const customer = await ctx.model.CustomerModel.findByPk(id);

      if (!customer) {
        ctx.error('客户不存在', 404);
        return;
      }

      // 开启事务处理
      const result = await ctx.model.transaction(async (t) => {
        // 更新客户信息
        await customer.update(customerData, { transaction: t });

        // 处理联系人信息
        if (customerData.contactPersons && Array.isArray(customerData.contactPersons)) {
          // 先删除现有的联系人
          await ctx.model.ContactPersonModel.destroy({
            where: { customerId: id },
            transaction: t
          });

          // 再创建新的联系人
          const contactPersons = customerData.contactPersons.map(contact => ({
            ...contact,
            customerId: id
          }));
          await ctx.model.ContactPersonModel.bulkCreate(contactPersons, { transaction: t });
        }

        // 重新查询客户信息，包含联系人
        return await ctx.model.CustomerModel.findByPk(id, {
          include: [
            {
              model: ctx.model.ContactPersonModel,
              as: 'contacts',
              attributes: ['id', 'name', 'phone', 'email', 'department', 'position', 'isPrimary', 'address', 'remark']
            }
          ],
          transaction: t
        });
      });

      ctx.success(result, '客户更新成功');
    } catch (error) {
      ctx.logger.error('更新客户失败:', error);
      ctx.error(`更新客户失败: ${error.message}`);
    }
  }

  // 删除客户
  async destroy() {
    const { ctx } = this;
    const { id } = ctx.params;

    try {
      const customer = await ctx.model.CustomerModel.findByPk(id);

      if (!customer) {
        ctx.error('客户不存在', 404);
        return;
      }

      // 检查是否有关联的销售订单
      const salesOrderCount = await ctx.model.SalesOrderModel.count({
        where: { customerId: id }
      });

      if (salesOrderCount > 0) {
        ctx.error('该客户有关联的销售订单，无法删除', 400);
        return;
      }

      // 删除客户
      await customer.destroy();

      ctx.success(null, '客户删除成功');
    } catch (error) {
      ctx.logger.error('删除客户失败:', error);
      ctx.error(`删除客户失败: ${error.message}`);
    }
  }

  // 批量删除客户
  async batchDelete() {
    const { ctx } = this;
    const { ids } = ctx.request.body;

    try {
      // 检查是否有关联的销售订单
      const salesOrders = await ctx.model.SalesOrderModel.findAll({
        where: { 
          customerId: {
            [ctx.app.Sequelize.Op.in]: ids
          }
        }
      });

      if (salesOrders.length > 0) {
        ctx.error('选中的客户中有关联的销售订单，无法删除', 400);
        return;
      }

      // 批量删除客户
      await ctx.model.CustomerModel.destroy({
        where: { 
          id: {
            [ctx.app.Sequelize.Op.in]: ids
          }
        }
      });

      ctx.success(null, `成功删除 ${ids.length} 个客户`);
    } catch (error) {
      ctx.logger.error('批量删除客户失败:', error);
      ctx.error(`批量删除客户失败: ${error.message}`);
    }
  }

  // 导出客户
  async exportCustomers() {
    const { ctx } = this;

    try {
      // 获取所有客户
      const customers = await ctx.model.CustomerModel.findAll({
        order: [['created_at', 'DESC']]
      });

      ctx.success(null, '客户导出成功');
    } catch (error) {
      ctx.logger.error('导出客户失败:', error);
      ctx.error(`导出客户失败: ${error.message}`);
    }
  }

  // 导入客户模板
  async exportTemplate() {
    const { ctx } = this;

    try {
      const XLSX = require('xlsx');

      // 创建工作簿
      const workbook = XLSX.utils.book_new();

      // 创建模板数据
      const templateData = [
        {
          '客户名称': '示例客户',
          '客户编码': 'CUS001',
          '联系人信息': '[{"name":"张经理","phone":"13800138000","email":"zhang@example.com"}]',
          '状态': '1',
          '备注': '示例客户备注'
        }
      ];

      // 创建工作表
      const worksheet = XLSX.utils.json_to_sheet(templateData);

      // 添加工作表到工作簿
      XLSX.utils.book_append_sheet(workbook, worksheet, '客户导入模板');

      // 写入缓冲区并返回
      const buffer = XLSX.write(workbook, { type: 'buffer', bookType: 'xlsx' });

      // 设置响应头
      ctx.set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
      ctx.set('Content-Disposition', 'attachment; filename=customer_import_template.xlsx');

      // 直接返回buffer，不使用标准响应格式
      ctx.body = buffer;
    } catch (error) {
      ctx.logger.error('生成导入模板失败:', error);
      ctx.error(`生成导入模板失败: ${error.message}`);
    }
  }

  // 导入客户
  async importCustomers() {
    const { ctx } = this;

    try {
      // 获取上传的文件
      const stream = await ctx.getFileStream();

      // 检查文件类型
      const filename = stream.filename.toLowerCase();
      if (!filename.endsWith('.xlsx') && !filename.endsWith('.csv')) {
        ctx.error('只支持.xlsx或.csv格式的文件', 400);
        return;
      }

      // 解析文件内容
      const XLSX = require('xlsx');
      const fs = require('fs');
      const path = require('path');

      // 保存上传的文件到临时位置
      const tempFilePath = path.join(__dirname, '../../temp', Date.now() + '_' + stream.filename);

      // 确保临时目录存在
      const tempDir = path.dirname(tempFilePath);
      if (!fs.existsSync(tempDir)) {
        fs.mkdirSync(tempDir, { recursive: true });
      }

      // 保存文件
      const writeStream = fs.createWriteStream(tempFilePath);
      stream.pipe(writeStream);

      // 等待文件保存完成
      await new Promise((resolve, reject) => {
        writeStream.on('finish', resolve);
        writeStream.on('error', reject);
      });

      // 读取并解析Excel文件
      const workbook = XLSX.readFile(tempFilePath);
      const sheetName = workbook.SheetNames[0];
      const worksheet = workbook.Sheets[sheetName];

      // 转换为JSON数据
      const jsonData = XLSX.utils.sheet_to_json(worksheet);

      // 验证并处理数据
      const validCustomers = [];
      const errors = [];

      for (let i = 0; i < jsonData.length; i++) {
        const row = jsonData[i];
        const rowIndex = i + 2; // +2 because header is row 1, and Excel is 1-indexed

        try {
          // 验证必填字段
          if (!row['客户名称']) {
            errors.push(`第${rowIndex}行: 客户名称为必填字段`);
            continue;
          }

          // 验证客户名称唯一性
          const existingCustomer = await ctx.model.CustomerModel.findOne({
            where: { name: row['客户名称'] }
          });

          if (existingCustomer) {
            errors.push(`第${rowIndex}行: 客户名称 ${row['客户名称']} 已存在`);
            continue;
          }

          // 构造客户数据
          const customerData = {
            name: row['客户名称'],
            code: row['客户编码'] || '',
            contactPersons: row['联系人信息'] || '[]',
            status: parseInt(row['状态']) || 1
          };

          validCustomers.push(customerData);
        } catch (rowError) {
          errors.push(`第${rowIndex}行: 数据格式错误 - ${rowError.message}`);
        }
      }

      // 如果有错误，返回错误信息
      if (errors.length > 0) {
        // 删除临时文件
        if (fs.existsSync(tempFilePath)) {
          fs.unlinkSync(tempFilePath);
        }

        ctx.error(`导入失败: \n${errors.join('\n')}`, 400);
        return;
      }

      // 批量插入客户数据
      if (validCustomers.length > 0) {
        await ctx.model.CustomerModel.bulkCreate(validCustomers);
      }

      // 删除临时文件
      if (fs.existsSync(tempFilePath)) {
        fs.unlinkSync(tempFilePath);
      }

      ctx.success({
        importedCount: validCustomers.length,
        errorCount: errors.length
      }, `成功导入${validCustomers.length}个客户`);
    } catch (error) {
      ctx.logger.error('导入客户失败:', error);
      ctx.error(`导入客户失败: ${error.message}`);
    }
  }

  // 获取客户统计信息
  async getStats() {
    const { ctx } = this;

    try {
      // 添加组织过滤条件
      const where = {};
      if (ctx.state.organizationId) {
        where.organizationId = ctx.state.organizationId;
      }

      const stats = await this.calculateCustomerStats(ctx, where);
      ctx.success(stats);
    } catch (error) {
      ctx.logger.error('获取客户统计信息失败:', error);
      ctx.error(`获取客户统计信息失败: ${error.message}`);
    }
  }

  // 计算客户统计数据
  async calculateCustomerStats(ctx, where) {
    // 总客户数
    const totalCustomers = await ctx.model.CustomerModel.count({ where });

    // 活跃客户数
    const activeCustomers = await ctx.model.CustomerModel.count({ 
      where: { 
        ...where,
        status: 1 
      } 
    });

    // 潜在客户数
    const potentialCustomers = await ctx.model.CustomerModel.count({ 
      where: { 
        ...where,
        customerLevel: 'potential' 
      } 
    });

    // 黑名单客户数
    const blacklistedCustomers = await ctx.model.CustomerModel.count({ 
      where: { 
        ...where,
        status: 0 
      } 
    });

    // 本月新增客户数
    const startDate = new Date();
    startDate.setDate(1);
    startDate.setHours(0, 0, 0, 0);

    const monthlyNewCustomers = await ctx.model.CustomerModel.count({ 
      where: { 
        ...where,
        created_at: {
          [ctx.app.Sequelize.Op.gte]: startDate
        }
      } 
    });

    // 本月交易金额 (需要关联销售订单)
    const salesOrders = await ctx.model.SalesOrderModel.findAll({
      where: {
        order_date: {
          [ctx.app.Sequelize.Op.gte]: startDate
        }
      },
      include: [{
        model: ctx.model.CustomerModel,
        as: 'customer',
        where: where,
        attributes: []
      }],
      attributes: [
        [ctx.app.Sequelize.fn('SUM', ctx.app.Sequelize.col('order_amount')), 'totalAmount']
      ],
      raw: true
    });

    const monthlyTransactionAmount = salesOrders[0].totalAmount || 0;

    // 客户活跃度 (示例计算)
    const customerActivityRate = totalCustomers > 0 ? Math.round((activeCustomers / totalCustomers) * 100) : 0;

    // 客户满意度 (示例值)
    const customerSatisfaction = 95;

    // 趋势数据 (示例值)
    const newCustomersTrend = 12;
    const transactionAmountTrend = 8;
    const activityRateTrend = 3;
    const satisfactionTrend = 1;

    return {
      totalCustomers,
      activeCustomers,
      potentialCustomers,
      blacklistedCustomers,
      monthlyNewCustomers,
      monthlyTransactionAmount,
      customerActivityRate,
      customerSatisfaction,
      newCustomersTrend,
      transactionAmountTrend,
      activityRateTrend,
      satisfactionTrend
    };
  }

  // 批量设置客户评分
  async batchSetRating() {
    const { ctx } = this;
    const { customerIds, rating } = ctx.request.body;

    try {
      // 参数验证
      if (!customerIds || !Array.isArray(customerIds) || customerIds.length === 0) {
        ctx.error('客户ID列表不能为空', 400);
        return;
      }

      if (rating === undefined || rating === null) {
        ctx.error('客户评分不能为空', 400);
        return;
      }

      // 批量更新客户记录
      const result = await ctx.model.CustomerModel.update(
        { creditScore: rating * 20 }, // 将评分转换为0-100分
        { where: { id: customerIds } }
      );

      ctx.success({
        updatedCount: result[0]
      }, `成功为${result[0]}个客户设置评分`);
    } catch (error) {
      ctx.logger.error('批量设置客户评分失败:', error);
      ctx.error(`批量设置客户评分失败: ${error.message}`);
    }
  }

  // 批量设置客户等级
  async batchSetLevel() {
    const { ctx } = this;
    const { customerIds, level } = ctx.request.body;

    try {
      // 参数验证
      if (!customerIds || !Array.isArray(customerIds) || customerIds.length === 0) {
        ctx.error('客户ID列表不能为空', 400);
        return;
      }

      if (!level) {
        ctx.error('客户等级不能为空', 400);
        return;
      }

      // 批量更新客户记录
      const result = await ctx.model.CustomerModel.update(
        { customerLevel: level },
        { where: { id: customerIds } }
      );

      ctx.success({
        updatedCount: result[0]
      }, `成功为${result[0]}个客户设置等级`);
    } catch (error) {
      ctx.logger.error('批量设置客户等级失败:', error);
      ctx.error(`批量设置客户等级失败: ${error.message}`);
    }
  }

  // 批量设置客户状态
  async batchSetStatus() {
    const { ctx } = this;
    const { customerIds, status } = ctx.request.body;

    try {
      // 参数验证
      if (!customerIds || !Array.isArray(customerIds) || customerIds.length === 0) {
        ctx.error('客户ID列表不能为空', 400);
        return;
      }

      if (!status) {
        ctx.error('客户状态不能为空', 400);
        return;
      }

      // 批量更新客户记录
      const result = await ctx.model.CustomerModel.update(
        { status: status },
        { where: { id: customerIds } }
      );

      ctx.success({
        updatedCount: result[0]
      }, `成功为${result[0]}个客户设置状态`);
    } catch (error) {
      ctx.logger.error('批量设置客户状态失败:', error);
      ctx.error(`批量设置客户状态失败: ${error.message}`);
    }
  }

  // 批量设置负责销售
  async batchSetResponsibleSalesman() {
    const { ctx } = this;
    const { customerIds, salesman } = ctx.request.body;

    try {
      // 参数验证
      if (!customerIds || !Array.isArray(customerIds) || customerIds.length === 0) {
        ctx.error('客户ID列表不能为空', 400);
        return;
      }

      if (!salesman) {
        ctx.error('销售负责人不能为空', 400);
        return;
      }

      // 批量更新客户记录
      const result = await ctx.model.CustomerModel.update(
        { responsibleSalesman: salesman },
        { where: { id: customerIds } }
      );

      ctx.success({
        updatedCount: result[0]
      }, `成功为${result[0]}个客户设置负责销售`);
    } catch (error) {
      ctx.logger.error('批量设置负责销售失败:', error);
      ctx.error(`批量设置负责销售失败: ${error.message}`);
    }
  }
}

module.exports = CustomerController;
